"""
Controller for the Worde blogging systems administration interface
"""

__revision__ = "$Id: admin.py 47 2007-03-12 13:57:13Z jens.persson $"
from turbogears import controllers, expose, validate, redirect, flash
from turbogears import identity, widgets, validators
from worde import model
from datetime import datetime


class PostFields(widgets.WidgetsList):
    """The fields used when creating posts"""
    title = widgets.TextField(validator=validators.NotEmpty(),
                              attrs = {'size':30},
                              label = _("Title"))
    author = widgets.TextField(validator=validators.NotEmpty(),
                               attrs = {'size':30},
                               label = _("Author"))
    text = widgets.TextArea(validator=validators.NotEmpty(),
                            label = _("Text"))
    tags = widgets.TextField(attrs={'size':30},
                             label = _("Tags"))
    created = widgets.CalendarDateTimePicker(
                 format="%Y-%m-%d %H:%M",
                 validator = validators.DateTimeConverter(
                                    if_empty=datetime.now(),
                                    format="%Y-%m-%d %H:%M"
                             ),
                 label = _("Created"),
             )
    published = widgets.CheckBox(label = _("Published"))


POSTFORM = widgets.TableForm(fields=PostFields(),
            submit = widgets.SubmitButton(label = _("Submit post")))

class Posts(controllers.Controller):
    """A controlor to handle the administration of posts"""
    @expose(template="worde.templates.admin_postlist")
    def index(self):
        """Show a list of "all" posts"""
        posts = model.Post.select(orderBy="-created")[:]
        return (dict(posts=posts, title=_("Posts")))


    @expose(template="worde.templates.admin")
    def edit(self, postid = None, **kw):
        """
        Display a form to add a new post, then check the returned
        items and if appropate create a post
        """
        if kw:
            @validate(form=POSTFORM)
            def get_errors(self, tg_errors=None, **data):
                "Helper function to validate input"
                return tg_errors, data
            tg_errors, data = get_errors(self, **kw)

            if not tg_errors:
                if postid:
                    post = model.Post.get(postid)
                    post.title = data["title"]
                    post.text = data["text"]
                    post.author = data["author"]
                    post.tags = data["tags"]
                    post.created = data["created"]
                    post.published = data["published"]
                    flash(_("Your post have been updated"))
                    redirect(post.permalink)
                else:
                    post = model.Post(title=data["title"], text=data["text"], author=data["author"],
                                      tags=data["tags"], created=data["created"],
                                      published=data["published"])
                    flash(_("Your post have been created"))
                    redirect(post.permalink)
            else:
                flash(_("Please fix the following errors: "))
        else:
            if postid:
                post = model.Post.get(postid)
                data = dict(title = post.title,
                            text = post.text,
                            author = post.author,
                            tags = post.tags,
                            published = post.published,
                            created = post.created)
            else:
                data = dict(created=datetime.now(), author=identity.current.user.display_name)

        return dict(form=POSTFORM, title=_("Add a new post"), data=data)


class Admin(controllers.Controller, identity.SecureResource):
    "Controller for the admin interface"
    require = identity.in_group("admin")

    posts = Posts()

    @expose(template="worde.templates.admin_main")
    def index(self):
        """
        Display a list of all configpages
        """
        pages = ((_("Handle posts"),"posts"),
                 (_("Generic configuration"),"configuration"),
                 (_("Plugin configuration"),"plugins"))
        return dict(pages=pages, title="Configuation")

    @expose(template="worde.templates.admin")
    def configuration(self, **kw):
        """
        Display a form to configure Worde, then check the returned
        items and if appropate update the configuration
        """
        fields = []
        for opt in model.Configuration.select(orderBy = "name"):
            fields.append(opt.widget(name=opt.name))
        configform = widgets.TableForm(fields=fields,
                                       action="configuration")
        if kw:
            @validate(form=configform)
            def get_errors(self, tg_errors=None, **data):
                "Helper function to validate input"
                return tg_errors, data
            tg_errors, data = get_errors(self, **kw)

            if not tg_errors:
                for opt in data:
                    config = model.Configuration.select(
                                        model.Configuration.q.name == opt)
                    config[0].value = data[opt]

                flash(_("Your configurations have been updated"))
                redirect("/")
            else:
                flash(_("Please fix the following errors: "))
        else:
            data = dict(created=datetime.now(), author=identity.current.user.display_name)

        return dict(form=configform, title=_("Update the configuration"), data=data)



    @expose(template="worde.templates.admin_plugins")
    def plugins(self, plug=None, move=None, active=None, **kw):
        """
        Display a form to select what plugins should be active,
        then check the returned items and if appropate update
        the configuration
        """
        if plug and move in ["up", "down"]:
            plugin = model.PluginConfiguration.get(plug)
            hook = str(plugin.hook)
            if move == "up":
                plugin.ordering -= 1
                model.PluginConfiguration.selectBy(hook=hook,
                           ordering = plugin.ordering)[0].ordering += 1
            else:
                plugin.ordering += 1
                model.PluginConfiguration.selectBy(hook=hook,
                           ordering = plugin.ordering)[0].ordering -= 1
            model.PluginConfiguration.normalize_ordering(hook)


        plugins = model.PluginConfiguration.select(orderBy = "name")
        if active:
            activeplugs = set([])
            for name in kw:
                if name[-7:] == "_active":
                    plug = int(name[:-7])
                    activeplugs.add(plug)
            for plug in plugins:
                plug.active = plug.id in activeplugs

        plugclasses = set([])
        plugsperclass = {}

        for p in plugins:
            if p.active:
                plugclasses.add(p.hook)
                plugsperclass[p.hook] = plugsperclass.get(p.hook, []) + [p]

        for c in plugclasses:
            plugsperclass[c].sort(cmp=lambda a, b: cmp(a.ordering, b.ordering))

        return dict(plugs = plugins, plugclasses = list(plugclasses),
                    plugsperclass = plugsperclass, title=_("Update the configuration"))